package etcd

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/sirupsen/logrus"
	"go.etcd.io/etcd/clientv3"
	"logAgent/common"
	"logAgent/tailfile"
	"time"
)

var (
	client *clientv3.Client
)

//代码连接etcd
func InitEtcd(address []string)(err error){
	client ,err = clientv3.New(clientv3.Config{
		Endpoints: address,
		DialTimeout: time.Second,
	})
	if err != nil {
		logrus.Info("connect etcd failed")
		return
	}
	logrus.Info("connect etcd success!")
	return
}

func PutValue() {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
	defer cancel()
	str := `[{"path":"./test.log","topic":"test"},{"path":"./test0.log","topic":"test"}]`
	_, err := client.Put(ctx, "etcd_key", str)
	if err != nil {
		fmt.Printf("put to etcd failed, err:%v", err)
		return
	}
}



//根据key获取etcd的value值
func EtcdGetConf(key string)(allConfig []common.CollectEntry, err error) {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second*2)
	defer cancel()
	resp, err := client.Get(ctx, key)
	//获取值失败
	if err != nil {
		fmt.Println("err is: ", err)
		logrus.Info("get etcd config message failed!")
		return
	}
	//key没有对应的value
	if len(resp.Kvs) == 0 {
		logrus.Info("the key has no value" )
		return
	}
	ret := resp.Kvs[0]
	//ret.Value为json格式的字符串
	err = json.Unmarshal(ret.Value, &allConfig)
	if err != nil {
		logrus.Info("unmarshall value failed!")
		return
	}
	return
}


func EtcdWatch(key string) {
	for {
		//key对应的value有变化时watchChan才会有值
		watchChan := client.Watch(context.Background(), key)
		logrus.Info("get watchChan value")
		for resp := range watchChan {
			for _, evt := range resp.Events {
				var newConf []common.CollectEntry
				fmt.Printf("type:%s key:%s value:%s\n", evt.Type, evt.Kv.Key, evt.Kv.Value)
				//如果是删除的话
				if evt.Type == clientv3.EventTypeDelete {
					logrus.Info("warning: delete all value from the key!")
					tailfile.SendNewConf(newConf)  //没有任何接受的话就是阻塞的
					continue
				}
				err := json.Unmarshal(evt.Kv.Value, &newConf)
				if err != nil {
					logrus.Errorf("json unmarshal new conf failed, err:%v", err)
					continue
				}
				//告诉tailfile模块该启用新配置了
				tailfile.SendNewConf(newConf)  //没有任何接收就是阻塞的
			}
		}
	}
}